package org.janon.httpproxy;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;

public class ClientReadFromServer implements Runnable
{
	private final int BUFFER_SIZE = 96000;
	private BufferedInputStream in = null;
	private BufferedOutputStream out = null;
	private HttpSession session = null;
	private boolean isConnect = false;
	private Thread thread = null;
	private RequestLogStream rls = null;

	public ClientReadFromServer(BufferedInputStream in, BufferedOutputStream out, HttpSession session, boolean isConnect, RequestLogStream rls)
	{
		this.in = in;
		this.out = out;
		this.session = session;
		this.isConnect = isConnect;
		this.rls = rls;

		thread = new Thread(HttpUtil.getThreadGroup(),this);
		thread.setPriority(Thread.MIN_PRIORITY);
		thread.start();
	}

	public void join()
	{
		try
		{
			thread.join();
		}
		catch (Exception e)
		{
		}
	}

	@SuppressWarnings("deprecation")
	public void stop()
	{
		thread.stop();
	}

	public void run()
	{
		int bytes_read = 0;
		byte[] buf;
		try
		{
			int contentLength = -1;
			if (!isConnect)
			{
				String temp;
				boolean hasDate = false, hasContentType = false, hasConnection = false, hasAcceptRanges = false, hasServer = false;
				while (true)
				{
					temp = HttpUtil.readLine(in);
					if (temp == null || temp.length() == 0)
						break;
					if (HttpUtil.startsWith(temp, "Content-Length: "))
					{
						try
						{
							contentLength = Integer.parseInt(temp.substring(16));
						}
						catch (NumberFormatException e)
						{
							contentLength = -2;
						}
					}
					else if(HttpUtil.startsWith(temp, "Date: "))
					{
						hasDate=true;
					}
					else if(HttpUtil.startsWith(temp, "Content-Type: "))
					{
						hasContentType=true;
					}
					else if(HttpUtil.startsWith(temp, "Connection: "))
					{
						hasConnection=true;
					}
					else if(HttpUtil.startsWith(temp, "Accept-Ranges: "))
					{
						hasAcceptRanges=true;
					}
					else if(HttpUtil.startsWith(temp, "Server: "))
					{
						hasServer=true;
					}
					out.write((temp + HttpUtil.CRLF).getBytes());
					Log.getInstance().writeRecordToFile(rls.getInputStream(), temp);
					out.flush();
				}
				if(!hasDate)
				{
					HttpUtil.sendHeaderDate(out);
				}
				if(!hasContentType)
				{
					HttpUtil.sendHeaderContentType(out);
				}
				if(!hasConnection)
				{
					HttpUtil.sendHeaderConnection(out);
				}
				if(!hasAcceptRanges)
				{
					HttpUtil.sendHeaderAcceptRanges(out);
				}
				if(!hasServer)
				{
					HttpUtil.sendHeaderServer(out);
				}
				out.write((HttpUtil.CRLF).getBytes());
				Log.getInstance().writeRecordToFile(rls.getInputStream(), "");
				out.flush();
			}

			if (!isConnect && contentLength >= 0)
			{
				buf = new byte[contentLength + 10];

				int tempBuf = 0;
				while ((bytes_read = in.read(buf)) != -1)
				{
					out.write(buf, 0, bytes_read);
					out.flush();
					Log.getInstance().writeRecordToFile(rls.getInputStream(), buf, 0, bytes_read);
					tempBuf += bytes_read;
					if (tempBuf >= contentLength)
					{
						break;
					}
				}
			}
			else
			{
				buf = new byte[BUFFER_SIZE];
				while ((bytes_read = in.read(buf)) != -1)
				{
					if(!HttpUtil.startsWith(new String(buf, 0, bytes_read), "X-Trickling: "))
					{
						out.write(buf, 0, bytes_read);
						out.flush();
						Log.getInstance().writeRecordToFile(rls.getInputStream(), buf, 0, bytes_read);
					}
				}
			}
		}
		catch (IOException e)
		{
		}
		finally
		{
			if(session!=null)
				session.close();
		}

	}

}
